#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
#define maxn 20001
#define maxm 100001
#define CEMENT 1
#define STONE 0

int n,m,k;
struct Edge {
	int u,v;
};
Edge make_edge(int u, int v){
	Edge temp; temp.u=u; temp.v=v; return temp;
}
vector<Edge> cement;
vector<Edge> stone;
vector<pair<Edge, int> > ans;
class UnionSet {
private:
	int father[maxn];
public:
	int find(int a){
		if(father[a]!=a)
			return father[a] = find(father[a]);
	}
	void unite(int a, int b){
		int fa = find(a);
		int fb = find(b);
		if(fa != fb) father[fa]=fb;
	}
	void clear(){
		for(int i=0; i<maxn; i++)
			father[i] = i;
	}
	UnionSet(){
		clear();
	}
}us, us2;

int main(){
	cin>>n>>m>>k;
	for(int i=0; i<m; i++){
		int u,v,c;
		cin>>u>>v>>c;
		if(c==CEMENT) cement.push_back(make_edge(u,v));
		else stone.push_back(make_edge(u,v));
	}
	
	for(auto e : cement){
		us.unite(e.u, e.v);
	}
	int cstone=0;
	for(auto estone : stone){
		if(cstone > k){
			cout<<"no solution"<<endl;
			return 0;
		}
		if(us.find(estone.u) != us.find(estone.v)){
			us.unite(estone.u, estone.v);
			us2.unite(estone.u, estone.v);
			ans.push_back(make_pair(estone, STONE));
			cstone++;
		}
	}
	for(auto estone : stone){
		if(cstone == k) break;
		if(us2.find(estone.u) != us2.find(estone.v)){
			us2.unite(estone.u, estone.v);
			ans.push_back(make_pair(estone, STONE));
			cstone++;
		}
	}
	if(cstone < k){
		cout<<"no solution"<<endl;
		return 0;
	}
	int cenum=0;
	for(auto e : cement){
		if(cenum+k == n-1) break;
		if(us2.find(e.u) != us2.find(e.v)){
			us2.unite(e.u, e.v);
			ans.push_back(make_pair(e, CEMENT));
			cenum++;
		}
	}
	
	for(auto e : ans)
		printf("%d %d %d\n", e.first.u, e.first.v, e.second);
	
	return 0;
}